local LLB = CreateFrame("Frame")
_G.LLB = LLB

local SPELL_NAME__Serpent_Sting = "毒蛇钉刺"
local SPELL_NAME__Scorpid_Sting = "毒蝎钉刺"
local SPELL_NAME__Viper_Sting = "蝰蛇钉刺"

local defaults = {
  multiShot = true,
  arcaneShot = true,
  useSmartSting = true,
  sting = "none",
  rapidFire = true,
  hunterMark = true,
}

LLB_DB = LLB_DB or {}

local db = {}

local function MergeDefaults(src, def)
  for k, v in pairs(def) do
    if src[k] == nil then
      src[k] = v
    end
  end
end

local function InitDB()
  MergeDefaults(LLB_DB, defaults)
  for k, v in pairs(LLB_DB) do
    db[k] = v
  end
end

local function Save()
  for k, v in pairs(db) do
    LLB_DB[k] = v
  end
end

local function GetWaterfall()
  return AceLibrary and AceLibrary:HasInstance("Waterfall-1.0") and AceLibrary("Waterfall-1.0")
end

local function UpdateStingControls()
  local dis = db.useSmartSting
  for _, n in ipairs {"viper", "scorpid", "serpent"} do
    LLB.options.args.stingGroup.args[n].disabled = dis
  end
  if dis then
    db.sting = "none";
    Save()
  end
end

local opt = {
  type = "group",
  name = "射击配置",
  args = {
    hunterMark = {
      type = "toggle",
      name = "猎人印记",
      get = function()
        return db.hunterMark
      end,
      set = function(v)
        db.hunterMark = v;
        Save()
      end,
      order = 5
    },
    multiShot = {
      type = "toggle",
      name = "多重射击",
      get = function()
        return db.multiShot
      end,
      set = function(v)
        db.multiShot = v;
        Save()
      end,
      order = 10
    },
    arcaneShot = {
      type = "toggle",
      name = "奥术射击",
      get = function()
        return db.arcaneShot
      end,
      set = function(v)
        db.arcaneShot = v;
        Save()
      end,
      order = 15
    },
    rapidFire = {
      type = "toggle",
      name = "急速射击",
      get = function()
        return db.rapidFire
      end,
      set = function(v)
        db.rapidFire = v;
        Save()
      end,
      order = 25
    },
    useSmartSting = {
      type = "toggle",
      name = "智能钉刺",
      get = function()
        return db.useSmartSting
      end,
      set = function(v)
        db.useSmartSting = v
        Save()
        UpdateStingControls({
          options = LLB.options
        })
      end,
      order = 35
    },
    stingGroup = {
      type = "group",
      name = "强制钉刺",
      order = 45,
      args = {
        viper = {
          type = "toggle",
          name = SPELL_NAME__Viper_Sting,
          get = function()
            return db.sting == SPELL_NAME__Viper_Sting
          end,
          set = function(v)
            db.sting = v and SPELL_NAME__Viper_Sting or "none";
            Save()
          end
        },
        scorpid = {
          type = "toggle",
          name = SPELL_NAME__Scorpid_Sting,
          get = function()
            return db.sting == SPELL_NAME__Scorpid_Sting
          end,
          set = function(v)
            db.sting = v and SPELL_NAME__Scorpid_Sting or "none";
            Save()
          end
        },
        serpent = {
          type = "toggle",
          name = SPELL_NAME__Serpent_Sting,
          get = function()
            return db.sting == SPELL_NAME__Serpent_Sting
          end,
          set = function(v)
            db.sting = v and SPELL_NAME__Serpent_Sting or "none";
            Save()
          end
        }
      }
    }
  }
}
LLB.options = opt

local regDone = false
local function RegisterWithWaterfall()
  if regDone then
    return
  end
  local Waterfall = GetWaterfall()
  if not Waterfall then
    return
  end
  UpdateStingControls({
    options = LLB.options
  })
  Waterfall:Register("LLB", "aceOptions", LLB.options, "treeLevels", 1)
  regDone = true
end

function LLB.Open()
  local Waterfall = GetWaterfall()
  if not Waterfall then
    DEFAULT_CHAT_FRAME:AddMessage("|cffff0000LLB 需要 Waterfall-1.0|r")
    return
  end
  if not regDone then
    RegisterWithWaterfall()
  end
  Waterfall:Open("LLB")
end

function LLB.GetDB()
  return db
end

LLB:SetScript("OnEvent", function()
  if event == "PLAYER_ENTERING_WORLD" then
    InitDB()
  end
end)
LLB:RegisterEvent("PLAYER_ENTERING_WORLD")

SLASH_LLB1 = "/llb"
SlashCmdList["LLB"] = function()
  LLB.Open()
end
